// 控制应用生命周期的模块。
// 创建原生浏览器窗口的模块。
const { app, BrowserWindow, Tray, Menu, ipcMain, shell } = require('electron')
//加载日志和更新
const log = require('electron-log');
const { autoUpdater } = require("electron-updater");
const config = require('./package.json')

log.info(process.env.NODE_ENV);

const IS_DEV = process.env.NODE_ENV === 'development' ? true : false

/*const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
    // Someone tried to run a second instance, we should focus our window.
    if (mainWindow) {
        mainWindow.show()
    }
})

if (shouldQuit) {
    app.quit()
}*/

const winURL = IS_DEV ? `http://localhost:8080/login.html` : `file://${__dirname}/html/dist/login.html`

//日志初始化操作
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'info';
log.info('App starting.....');

// 保持一个对于 window 对象的全局引用，如果你不这样做，
// 当 JavaScript 对象被垃圾回收， window 会被自动地关闭
let mainWindow
let updateChannel = null
let tray = null

function sendToUpdateChannel(jsonMsg) {
    updateChannel.sender.send('_checkUpdatesMessage', jsonMsg)
}

function createWindow() {
    // 创建浏览器窗口。
    let options = {
        width: 393,
        height: 500,
        resizable: false,
        transparent: true,
        frame: false
    }

    if (IS_DEV) options.webPreferences = { webSecurity: false }
    let firstWindow = new BrowserWindow(options)

    // 加载应用的 index.html。
    firstWindow.loadURL(winURL)

    // firstWindow.setSkipTaskbar(true)

    // 启用开发工具。
    // firstWindow.webContents.openDevTools()

    //兼容win7无法获取焦点
    firstWindow.webContents.on('did-finish-load', () => {
        if (!firstWindow) {
            throw new Error('"mainWindow" is not defined');
        }
        firstWindow.show();
        firstWindow.focus();
    });


    /*mainWindow.on('show', () => {
      tray.setHighlightMode('always')
    })
    mainWindow.on('hide', () => {
      tray.setHighlightMode('never')
    })*/


    // 当 window 被关闭，这个事件会被触发。
    firstWindow.on('closed', () => {
        // 取消引用 window 对象，如果你的应用支持多窗口的话，
        // 通常会把多个 window 对象存放在一个数组里面，
        // 与此同时，你应该删除相应的元素。
        firstWindow = null
    })

    return firstWindow
}

// Electron 会在初始化后并准备
// 创建浏览器窗口时，调用这个函数。
// 部分 API 在 ready 事件触发后才能使用。
app.on('ready', function() {
    mainWindow = createWindow()
    // creatTray()
})

// 当全部窗口关闭时退出。
app.on('window-all-closed', () => {
    // 在 macOS 上，除非用户用 Cmd + Q 确定地退出，
    // 否则绝大部分应用及其菜单栏会保持激活。
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

app.on('activate', () => {
    // 在 macOS 上，当点击 dock 图标并且该应用没有打开的窗口时，
    // 绝大部分应用会重新创建一个窗口。
    if (mainWindow === null) {
        mainWindow = createWindow()
        // creatTray()
    }
})

function creatTray() {
    tray = new Tray(require('path').join(__dirname, 'static/img/lit.png'))
    const contextMenu = Menu.buildFromTemplate([{
        label: '退出',
        click() {
            // mainWindow.webContents.send('deletelocalstorage', true)
            app.quit()
        }
    }])
    tray.setToolTip('美易通')
    tray.setContextMenu(contextMenu)

    tray.on('click', () => {
        mainWindow.show()
    })
}





// 在这文件，你可以续写应用剩下主进程代码。
// 也可以拆分成几个文件，然后用 require 导入。


/**********************************更新操作开始********************************/

// 定义发送参数
let sendMsg = {
    percent: 0,
    msg: '',
    success: false,
    isreStart: false
}
autoUpdater.on('checking-for-update', (ev, info) => {
    sendMsg.msg = '开始检全局更新...'
    sendToUpdateChannel(sendMsg)
})
// 没有大版本更新检查小版本更新
autoUpdater.on('update-not-available', (ev, info) => {
    sendMsg.msg = '开始检查局部更新...'
    sendToUpdateChannel(sendMsg)
    checkUpdates()
})
//有更新时操作
autoUpdater.on('update-available', (ev, info) => {
    //有更新开更新窗口
    sendMsg.msg = '开始下载更新！'
    sendToUpdateChannel(sendMsg)
})
//错误提示
autoUpdater.on('error', (ev, err) => {
    sendMsg.msg = '网络错误，请重新启动程序！'
    sendMsg.percent = '100%'
    sendMsg.success = true
    sendToUpdateChannel(sendMsg)
})
//更新进度
autoUpdater.on('download-progress', (ev, progressObj) => {
    // 获取速度
    let speed = 0,
        size = 0,
        percent = 0
    speed = (ev.bytesPerSecond / 1024).toFixed(2)
    speed = speed > 1024 ? (speed / 1024).toFixed(2) + 'M/s' : speed + 'kb/s'
    // 大小
    size = (ev.total / 1024).toFixed(2)
    size = size > 1024 ? (size / 1024).toFixed(2) + 'M' : size + 'kb'
    // 百分比
    percent = ev.percent.toFixed(2) + '%'

    sendMsg.percent = percent
    sendMsg.msg = `正在更新，总计${size}, 速度${speed}, 进度${percent}`

    sendToUpdateChannel(sendMsg)
})
//退出并安装
autoUpdater.on('update-downloaded', (ev, info) => {
    autoUpdater.quitAndInstall();
});

/**********************************更新操作结束********************************/



/**********************************主进程监听事件**********************************/

// 监听更新事件
ipcMain.on('_checkUpdates', (event) => {
    updateChannel = event
    // 大版本更新
    if (IS_DEV) {
        sendMsg.percent = '100%'
        sendMsg.success = true
        sendToUpdateChannel(sendMsg)
    } else {
        autoUpdater.checkForUpdates()
    }
    // checkUpdates()
})

// 监听主窗口重置
/*ipcMain.on('_changeMainWindow', (event, winId) => {
    mainWindow = BrowserWindow.fromId(winId)
})*/


/**********************************主进程监听事件**********************************/
const request = require('request')
const progress = require('request-progress')
const patchFs = require('electron-patch-fs')
const fs = require('fs')



// 检查更新
function checkUpdates() {
    // http://meiyitong.oss-cn-shanghai.aliyuncs.com/app.txt
    request('http://meiyitong.oss-cn-shanghai.aliyuncs.com/app.json', function(err, response, body) {
        // 如果错误提示更新失败请重启
        if (err) {
            sendMsg.msg = '更新失败请重启!'
            sendToUpdateChannel(sendMsg)
            return false
        }
        if (response.statusCode === 404) {
            sendMsg.percent = '100%'
            sendMsg.success = true
            sendToUpdateChannel(sendMsg)
        } else {
            let newVersion = JSON.parse(body)
            // 先判断服务器上的包是不是当前版本的包
            if (checkBigVersion(newVersion.smallVersion, config.smallVersion)) {
                // 执行更新操作
                downloadSmallUpdates()
            } else {
                // 已经是最新包
                sendMsg.percent = '100%'
                sendMsg.success = true
                sendToUpdateChannel(sendMsg)
            }
        }
    })
}

// 下载更新
function downloadSmallUpdates() {
    // 发送请求是否有更新
    // 直接下载文件 http://meiyitong.oss-cn-shanghai.aliyuncs.com/app.asar
    let speed = 0,
        size = 0,
        percent = 0

    patchFs.patch()
    progress(request('http://meiyitong.oss-cn-shanghai.aliyuncs.com/app.asar'))
        .on('progress', function(state) {
            // 开始下载更新
            //下载速度，总计大小， 百分比

            // 获取速度
            speed = (state.speed / 1024).toFixed(2)
            speed = speed > 1024 ? (speed / 1024).toFixed(2) + 'M/s' : speed + 'kb/s'
            // 大小
            size = (state.size.total / 1024).toFixed(2)
            size = size > 1024 ? (size / 1024).toFixed(2) + 'M' : size + 'kb'
            // 百分比
            percent = (state.percent * 100).toFixed(2) + '%'

            sendMsg.percent = percent
            sendMsg.msg = `正在更新，总计${size}, 速度${speed}, 进度${percent}`

            // 发送数据
            sendToUpdateChannel(sendMsg)
        })
        .on('end', function() {
            sendMsg.percent = '100%'
            sendMsg.msg = '开始替换文件！'
            sendToUpdateChannel(sendMsg)
        })
        .pipe(fs.createWriteStream('./resources/app.asar'))
        .on('finish', () => {
            // 执行加载函数
            patchFs.unpatch()
            sendMsg.success = true
            sendMsg.isreStart = true
            // 等待patchFs.unpatch()执行完成延时执行
            sendToUpdateChannel(sendMsg)
        })
}




//打印操作
const os = require('os')
const path = require('path')

ipcMain.on('print-now', function(event) {
    let pdfPath = path.join(os.tmpdir(), 'print.pdf')
    let win = BrowserWindow.fromWebContents(event.sender)
    win.webContents.print({ silent: true, printBackground: false });
})

ipcMain.on('print-to-pdf', function(event) {
    let pdfPath = path.join(os.tmpdir(), 'print.pdf')
    let win = BrowserWindow.fromWebContents(event.sender)
    win.webContents.printToPDF({ marginsType: 1, pageSize: { width: 70000, height: 210000 } }, function(error, data) {
        if (error) throw error
        fs.writeFile(pdfPath, data, function(error) {
            if (error) {
                throw error
            }
            shell.openExternal('file://' + pdfPath)
            //event.sender.send('wrote-pdf', pdfPath)
        })
    })
})


// 判断v1是否大于v2
function checkBigVersion(v1, v2) {
    v1 = v1.split('.')
    v2 = v2.split('.')
    // 先用文字描述逻辑
    // 首先如果主版本1大于主版本2，说明1大
    // 如果主版本1等于主版本2 继续往下比较
    let i = 0
    let len = v1.length
    while (i < len) {
        if (Number(v1[i]) === Number(v2[i])) {
            i++
            continue
        }
        return Number(v1[i]) > Number(v2[i]) ? true : false
    }
    return false
}